// ========================================================================
// Copyright (c) 2022 ChangYou, All rights reserved.
// http://www.changyou.com/
// 
// Filename:    UNMap.cs
// Time:        2022-08-22 20:42:17
// Author:      xiangjinbao
// Email:       xiangjinbao@cyou-inc.com
// Version:     v2022.0.1
// Description: UNMap
// ========================================================================

using System;
using UnityEngine;

namespace ProjectTW.Foliage
{
    /// <summary>
    /// The abstract Map class.
    /// </summary>
    [Serializable]
    public abstract class FoliageMapBase
    {
        // 序列化图
        [SerializeField]
        protected Texture2D m_Map;
        // 快速访问图像素信息
        [NonSerialized]
        internal Color32[] m_MapPixels;
        // 图的宽 （宽和高相同）
        [SerializeField]
        private int m_MapWidth;
        // 图对应实例
        [SerializeField]
        private FoliageChunk m_FoliageInstance;

        // 是否被标记巍脏
        [NonSerialized]
        private bool m_Dirty = false;
        // 是否被保存
        [NonSerialized]
        private bool m_SaveDelayed = false;

        public Texture2D Map
        {
            get
            {
                return m_Map;
            }
            set
            {
                if (m_Map != value)
                {
                    m_Map = value;
                    m_MapPixels = Map == null ? null : Map.GetPixels32();
                }
            }
        }

        public Color32[] MapPixels
        {
            get
            {
                if (m_MapPixels == null)
                {
                    m_MapPixels = Map.GetPixels32();
                }

                return m_MapPixels;
            }
            internal set
            {
                m_MapPixels = value;
            }
        }

        public int MapWidth
        {
            get
            {
                return m_MapWidth;
            }
        }

        public bool Dirty
        {
            get
            {
                return m_Dirty;
            }
            set
            {
                if (m_Dirty != value)
                {
                    m_Dirty = value;

#if UNITY_EDITOR
                    if (!Application.isPlaying && Map != null && value)
                    {
                        UnityEditor.EditorUtility.SetDirty(Map);
                    }
#endif

                    OnDirty(value);
                }
            }
        }

        private bool SaveDelayed
        {
            get
            {
                return m_SaveDelayed;
            }
            set
            {
                if (m_SaveDelayed != value)
                {
                    m_SaveDelayed = value;

                    if (value && !FoliageManager.FoliageMapsWaitingForSave.Contains(this))
                    {
                        FoliageManager.FoliageMapsWaitingForSave.Add(this);
                    }
                }
            }
        }

        public FoliageChunk FoliageInstance
        {
            get
            {
                return m_FoliageInstance;
            }
        }

        protected FoliageMapBase()
        {
        }

        protected FoliageMapBase(Texture2D texture, Color32[] pixels, FoliageChunk foliageInstance)
        {
            m_Map = texture;
            m_FoliageInstance = foliageInstance;

            Apply(pixels);
        }

        public void Apply(Color32[] pixels)
        {
            m_MapPixels = pixels;
            m_MapWidth = m_Map.width;

            Map.Apply();

            Dirty = false;

#if UNITY_EDITOR
            UnityEditor.EditorUtility.SetDirty(Map);
#endif
        }

        protected virtual void OnDirty(bool value)
        {
        }

        public void SetPixels32()
        {
            SetPixels32(MapPixels);
        }

        public void SetPixels32(Color32[] pixels)
        {
            SetPixels32(pixels, true);
        }

        public void SetPixelsNoApply()
        {
            SetPixels32(MapPixels, false);
        }

        public void SetPixels32Delayed()
        {
            m_Dirty = true;
            SaveDelayed = true;
        }

        public void ApplySetPixelsDelayed()
        {
            if (SaveDelayed)
            {
                SaveDelayed = false;

                SetPixels32();
            }
        }

        private void SetPixels32(Color32[] pixels, bool apply)
        {
            if (Map == null)
            {
                return;
            }

            Map.SetPixels32(pixels);
            if (apply)
            {
                Apply(pixels); // apply changes
            }
        }

        public void Resize(int size)
        {
            Map.Resize(size, size);
            m_MapWidth = size;
            m_MapPixels = Map.GetPixels32();

            Clear(true, Color.black);
        }

        public void Clear(bool autoApply, Color32 defaultColor)
        {
            int mapWidth = this.MapWidth;

            m_MapPixels = FoliageMapUtility.PoolColors(mapWidth);

            if (autoApply)
            {
                SetPixels32();
            }
        }

        public virtual void Dispose()
        {
        }
    }
}
